#include "Arduino.h"
#include "Speaker.h"
#include "definitions.h"

//Much (most) of this code i borrowed from here
//http://forum.sparkfun.com/viewtopic.php?f=14&t=21388
//All hail the creator Maleche

Speaker::Speaker(){

}

void Speaker::stopPlayBack(){
	sendProperCommand(_Stop);  
}

void Speaker::prepare(){
	_minVol= 0xfff0;    // Minimum volume
	_maxVol= 0xfff7;    // Max Volume   
	_PlyPse = 0xfffe;   // Play or Pause
	_Stop= 0xFFFF;      // Stop
	
	_pinClock= SOMOCLOCK_DIGITAL_OUT_PIN;
	_pinData =SOMODATA_DIGITAL_OUT_PIN;
	_pinBusy =SOMOBUSY_DIGITAL_IN_PIN;
	_pinReset=SOMORESET_DIGITAL_OUT_PIN;
	_volLevel=0x0005;
	_Song = 0;                             // current Song
	_vol = _maxVol;                     // current volume 

	pinMode(_pinData,OUTPUT);     // set pin 4 to output for Data
	pinMode(_pinClock,OUTPUT);    // set pin 3 to output for data
	pinMode(_pinReset,OUTPUT);    // set pin 7 to allow software reset
	pinMode(_pinBusy,INPUT);      // set pin 6 to monitor while Song is playing
	reset();   
}

void Speaker::playAudioFile(unsigned int file){
  //if (isBusy()) { stopPlayBack(); }
	sendProperCommand(file); 
	//Serial.print("Playing file: ");
	//Serial.println(file);
}

boolean Speaker::isBusy(){
  return digitalRead(_pinBusy) == HIGH;
}

void Speaker::sendProperCommand(unsigned int command){
 // start bit
  digitalWrite(_pinClock, LOW);
  delay(2);

  // bit15, bit14, ... bit0
  for (unsigned int mask = 0x8000; mask > 0; mask >>= 1) {
    if (command & mask) {
      digitalWrite(_pinData, HIGH);
    }
    else {
      digitalWrite(_pinData, LOW);
    }
    // clock low
    digitalWrite(_pinClock, LOW);
    delayMicroseconds(200);

    // clock high
    digitalWrite(_pinClock, HIGH);
    delayMicroseconds(200);
  }

  // stop bit
  delay(2);
  
  
  
  
  }

void Speaker::sendCommand(int ThisCommand){
	int TheCommand = ThisCommand;
	int ClockCounter=0;
	int ClockCycle=15;//0x0f;
	
	digitalWrite(_pinClock,HIGH);     // Hold (idle) for 300msec to prepare data start
	delay(300); 
	digitalWrite(_pinClock,LOW);       //Hold for 2msec to signal data start
	delay(2);  //2msec delay
	
	while(ClockCounter <= ClockCycle){
		digitalWrite(_pinClock,LOW); 
		if (TheCommand & 0x8000){
			digitalWrite(_pinData,HIGH);
		}
		else{
			digitalWrite(_pinData,LOW);
		}
		TheCommand = TheCommand << 1;
		delayMicroseconds(200);      //Clock cycle period is 200 uSec - LOW
		digitalWrite(_pinClock,HIGH);
		ClockCounter++;
		delayMicroseconds(200);      //Clock cycle period is 200 uSec - HIGH
	}
	digitalWrite(_pinData,LOW);
//	digitalWrite(_pinClock,HIGH);    // Place clock high to signal end of data
}

void Speaker::reset(){  // reset the module
  digitalWrite(_pinReset, HIGH);
  delay(100);
  digitalWrite(_pinReset, LOW);
  delay(10);
  digitalWrite(_pinReset, HIGH);
  delay(100);
  sendProperCommand(0xFFF7); //volum på fult
}
